import {enterFullscreen} from "./fullScreen.js";
import {artificialAlarm} from "./artificialAlarm.js";
import {mappingCameraId2RoomId} from "./mappingCameraId2RoomId.js";
import {socket} from "./socket.js";
import {cameraId2RoomId} from "./cameraConfig.js";
import {check_alarm,sleep} from "./utils.js";
import {FIRE_CONFIDENCE_THRESHOLD,SMOKE_CONFIDENCE_THRESHOLD,MAX_FRAME_COUNT,PROPORTION_THRESHOLD} from "./alarmConfig.js"

// 设备管理类
class CameraManager {
  constructor() {
    this.cameras = new Map(); // 存储摄像头流和状态
    this.intervalIds = new Map(); // 存储采样定时器
  }

  // 发现并初始化所有摄像头
  async initCameras() {
    const devices = await navigator.mediaDevices.enumerateDevices();
    const videoInputs = devices.filter(d => d.kind === 'videoinput');

    for (const device of videoInputs) {
      try {
        const stream = await navigator.mediaDevices.getUserMedia({
          video: { deviceId: { exact: device.deviceId } }
        });

        this.cameras.set(device.deviceId, {
          stream,
          deviceInfo: device,
          canvas: document.createElement('canvas'),
          active: false
        });

        console.log(`摄像头 ${device.label} 初始化成功`);
      } catch (err) {
        console.error(`无法访问摄像头 ${device.label}:`, err);
      }
    }
  }
  // 开始采样指定摄像头
  startSampling(deviceId, socket = null,interval = 1000) {
    const camera = this.cameras.get(deviceId);
    if (!camera) return;

    const { stream, canvas } = camera;
    const videoTrack = stream.getVideoTracks()[0];
    const settings = videoTrack.getSettings();
    const { width, height } = settings;

    canvas.width = width;
    canvas.height = height;
    const ctx = canvas.getContext('2d');
    const video = document.createElement('video');

    video.srcObject = stream;
    video.autoplay = true;

    // 清除现有定时器
    if (this.intervalIds.has(deviceId)) {
      clearInterval(this.intervalIds.get(deviceId));
    }

    // 设置新的采样定时器
    const intervalId = setInterval(() => {
      if (video.readyState >= video.HAVE_ENOUGH_DATA) {
        ctx.drawImage(video, 0, 0, width, height);

        // 将帧转换为JPEG并发送到后端
        canvas.toBlob(blob => {
            this.sendFrame(socket,deviceId, blob);
        }, 'image/jpeg', 0.7); // 质量参数0.7平衡大小和画质
      }
    }, interval);

    this.intervalIds.set(deviceId, intervalId);
    camera.active = true;
  }
  stopSampling(deviceId){
    // 清除现有定时器,清除了应该就没事了吧。。
    if (this.intervalIds.has(deviceId)) {
      clearInterval(this.intervalIds.get(deviceId));
      console.log(`清除定时器，${deviceId}`);
    }
  }
  // 发送帧到后端
  sendFrame(socket,deviceId, blob) {
    let data = {deviceId:deviceId,frame:blob};
    socket.emit("camera_frame",data);
    console.log(`socket emit to "camera_frame" ${data}`);
  }

}
let frame_count = MAX_FRAME_COUNT;
let delay_time = 3;
const artAlarm = new artificialAlarm();
// 摄像头功能示例  等会弄需要多摄像头
let camera_state = 0;
const startCameraBtn = document.getElementById('start-camera-btn');
const stopCameraBtn = document.getElementById('stop-camera-btn');
const statusText = document.getElementById('statusText');
const cameraCount = document.getElementById('cameraCount');
const cameraResults = document.getElementById('camera-results'); //摄像头处理后显示框
const cameraAlarmContainer = document.getElementById('camera-alarm-container');
const cameraSampleRate = document.getElementById('camera-sample-rate');
const applyCameraSampleRate = document.getElementById('apply-camera-rate-btn');
let sample_interval = cameraSampleRate.value;
frame_count = Math.min(Math.floor(1000/sample_interval*delay_time),MAX_FRAME_COUNT);
console.log(`frame count 被设置为${frame_count}`);
let camera_example = `
                    <div class="bg-white rounded-lg shadow-sm overflow-hidden hover:shadow-md transition-all duration-200">
                        <div class="relative">
                            <img src="https://picsum.photos/600/400?random=4" alt="摄像头4" class="w-full h-48 object-cover">
                            <div class="absolute top-2 left-2 bg-black/60 text-white text-sm px-2 py-1 rounded-md">
                                <span class="font-medium">Room:</span>
                            </div>
                            <button class="absolute bottom-2 right-2 bg-white/80 hover:bg-white text-gray-800 p-1.5 rounded-full transition-colors duration-200" onclick="toggleFullscreen('camera-4')">
                                <i class="fa fa-expand"></i>
                            </button>
                        </div>
                        <div class="p-3 flex justify-between items-center">
                            <span class="px-2 py-1 bg-green-100 text-green-800 rounded-full text-sm">CameraID:</span>
                            <span class="text-xs text-gray-500">Video001</span>
                        </div>
                    </div>
`;
let result = '';
for(let i=0; i<50; i++){
    result += camera_example;
}
cameraResults.innerHTML = result;
// 更新状态显示
function updateStatus(text, isActive = false) {
    const indicator = statusText.querySelector('.status-indicator');
    const textSpan = statusText.querySelector('span:last-child');

    textSpan.textContent = text;
    indicator.className = isActive
        ? 'status-indicator bg-green-500 animate-pulse'
        : 'status-indicator bg-gray-400';
}
let streamList = [];
let video_input_list = [];
let cameras_frames = new Map();
// 停止所有流
function stopAllStreams() {
    streamList.forEach(stream => {
        stream.getTracks().forEach(track => track.stop());
    });
    streamList = [];
}
async function getCameras(){
    stopAllStreams();
    cameraResults.innerHTML="";
    updateStatus('正在检测摄像头...');
    try {
        // 获取所有媒体设备
        const devices = await navigator.mediaDevices.enumerateDevices();
        console.log(devices);
        const videoInputs = devices.filter(device => device.kind === 'videoinput');
        video_input_list = videoInputs;
        console.log(videoInputs);
        cameraCount.textContent = videoInputs.length;
        if (videoInputs.length === 0) {
            updateStatus('未检测到摄像头设备');
            cameraResults.innerHTML = `
                <div class="col-span-full text-center py-12">
                    <div class="inline-flex items-center justify-center w-16 h-16 rounded-full bg-gray-100 mb-4">
                        <i class="fa fa-video-camera text-gray-400 text-2xl"></i>
                    </div>
                    <h3 class="text-lg font-medium text-gray-900 mb-2">未找到摄像头设备</h3>
                    <p class="text-gray-500 max-w-md mx-auto">请确保您的摄像头已正确连接并被系统识别。</p>
                </div>
            `;
            return;
        }
        updateStatus(`已检测到 ${videoInputs.length} 个摄像头`, true);
        // 为每个摄像头创建视频流
        for (const [index, device] of videoInputs.entries()) {
            try {
                const stream = await navigator.mediaDevices.getUserMedia({
                    video: { deviceId: { exact: device.deviceId } }
                });
                console.log(`stream${stream}`);
                // 能获取stream，加入device行列
                cameras_frames.set(device.deviceId,{
                    isLoading:false,
                    frames:[],
                    recentFireConfidences:[],
                    recentSmokeConfidences:[]
                });
                streamList.push(stream);
                createCameraCard(device);
            } catch (err) {
                console.error(`无法访问摄像头 ${device.label || `摄像头 ${index + 1}`}:`, err);
                createErrorCard(device, index, err);
            }
        }
    } catch (err) {
        console.error('枚举设备时出错:', err);
        updateStatus('访问摄像头时出错');
        cameraResults.innerHTML = `
            <div class="col-span-full text-center py-12">
                <div class="inline-flex items-center justify-center w-16 h-16 rounded-full bg-red-50 mb-4">
                    <i class="fa fa-exclamation-triangle text-red-500 text-2xl"></i>
                </div>
                <h3 class="text-lg font-medium text-gray-900 mb-2">访问摄像头时出错</h3>
                <p class="text-gray-500 max-w-md mx-auto">请确保您已授予摄像头访问权限。</p>
                <pre class="mt-4 text-sm text-red-600 bg-red-50 p-4 rounded overflow-x-auto">${err.message}</pre>
            </div>
        `;
    }
}

// 创建摄像头卡片
function createCameraCard(device) {
    const card = document.createElement('div');
    card.id = device.deviceId;
    card.classList.add('bg-white', 'rounded-lg', 'shadow-sm' ,'overflow-hidden' ,'hover:shadow-md' ,'transition-all', 'duration-200');
    let room = mappingCameraId2RoomId(device.deviceId,cameraId2RoomId);
    card.innerHTML = `
        <div class="relative">
            <img src="https://picsum.photos/600/400?random=4" alt="摄像头" class="w-full h-48 object-cover">
            <div class="absolute top-2 left-2 bg-black/60 text-white text-sm px-2 py-1 rounded-md">
                <span class="font-medium">Room:${room}</span>
            </div>
            <button class="absolute bottom-2 right-2 bg-white/80 hover:bg-white text-gray-800 p-1.5 rounded-full transition-colors duration-200">
                <i class="fa fa-expand"></i>
            </button>
        </div>
        <div class="p-3 flex items-center group">
            <!-- 设备图标 -->
            <div class="w-6 h-6 bg-green-100 rounded-full flex items-center justify-center mr-2 transition-all duration-200 group-hover:bg-green-200">
                <i class="fa fa-video-camera text-green-600 text-xs"></i>
            </div>

            <!-- 设备标签（主显示，自动截断） -->
            <div class="relative flex-grow">
                <span class="text-gray-800 font-medium text-sm truncate block hover:text-green-700 transition-colors duration-200"
                      title="${device.label} ${device.deviceId}">
                    ${device.label}
                </span>

                <!-- 悬停提示（显示完整标签和设备ID） -->
                <div class="absolute bottom-full left-0 mb-1 bg-gray-800 text-white text-xs rounded px-3 py-2 shadow-lg whitespace-nowrap opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200 transform group-hover:translate-y-0 translate-y-1 z-10">
                    <div class="flex items-center gap-2">
                        <div class="w-5 h-5 bg-green-100 rounded-full flex items-center justify-center">
                            <i class="fa fa-info-circle text-green-600 text-xs"></i>
                        </div>
                        <div>
                            <div class="font-medium mb-1">${device.label}</div>
                            <div class="text-gray-300 text-[10px]">${device.deviceId}</div>
                        </div>
                    </div>
                </div>
            </div>

            <!-- 状态指示器 -->
            <div class="ml-2 w-2 h-2 bg-green-500 rounded-full animate-pulse"></div>
        </div>
    `;

    // 全屏按钮
    let fullScreenBtn = card.querySelector('button');
    let video_frame = card.querySelector('img');
    fullScreenBtn.addEventListener('click',()=>{
        enterFullscreen(video_frame);
    });

    cameraResults.appendChild(card);
}
// 创建错误卡片
function createErrorCard(device) {
    const card = document.createElement('div');
    console.log(device);
    card.id = device.deviceId;
    card.classList.add('bg-white', 'rounded-lg', 'shadow-sm' ,'overflow-hidden' ,'hover:shadow-md' ,'transition-all', 'duration-200');
    let room =mappingCameraId2RoomId(device.deviceId,cameraId2RoomId);
    card.innerHTML = `
        <div class="relative">
            <!-- 摄像头预览区域 -->
            <div class="w-full h-48 relative">
                <!-- 错误提示（默认隐藏，通过JS控制显示） -->
                <div
                    id="camera-error"
                    class="absolute inset-0 bg-black/80 flex items-center justify-center text-white text-2xl font-bold"
                >
                    无法访问此摄像头
                </div>
            </div>

            <!-- 摄像头信息标签 -->
            <div class="absolute top-2 left-2 bg-black/60 text-white text-sm px-2 py-1 rounded-md">
                <span class="font-medium">Room:${room}</span>
            </div>

            <!-- 全屏按钮 -->
            <button
                class="absolute bottom-2 right-2 bg-white/80 hover:bg-white text-gray-800 p-1.5 rounded-full transition-colors duration-200"
                onclick="toggleFullscreen(${device.deviceId})"
            >
                <i class="fa fa-expand"></i>
            </button>
        </div>
        <div class="p-3 flex items-center group">
            <!-- 设备图标 -->
            <div class="w-6 h-6 bg-green-100 rounded-full flex items-center justify-center mr-2 transition-all duration-200 group-hover:bg-green-200">
                <i class="fa fa-video-camera text-green-600 text-xs"></i>
            </div>

            <!-- 设备标签（主显示，自动截断） -->
            <div class="relative flex-grow">
                <span class="text-gray-800 font-medium text-sm truncate block hover:text-green-700 transition-colors duration-200"
                      title="${device.label} ${device.deviceId}">
                    ${device.label}
                </span>

                <!-- 悬停提示（显示完整标签和设备ID） -->
                <div class="absolute bottom-full left-0 mb-1 bg-gray-800 text-white text-xs rounded px-3 py-2 shadow-lg whitespace-nowrap opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200 transform group-hover:translate-y-0 translate-y-1 z-10">
                    <div class="flex items-center gap-2">
                        <div class="w-5 h-5 bg-green-100 rounded-full flex items-center justify-center">
                            <i class="fa fa-info-circle text-green-600 text-xs"></i>
                        </div>
                        <div>
                            <div class="font-medium mb-1">${device.label}</div>
                            <div class="text-gray-300 text-[10px]">${device.deviceId}</div>
                        </div>
                    </div>
                </div>
            </div>

            <!-- 状态指示器 -->
            <div class="ml-2 w-2 h-2 bg-green-500 rounded-full animate-pulse"></div>
        </div>
    `;

    cameraResults.appendChild(card);
}
// 创建manager实例为开始按钮注册监听。
let manager = new CameraManager();
startCameraBtn.addEventListener('click', async () => {
    artAlarm.isStopped = false;
    // 还需要修改，创建需要的全局变量。
    await getCameras();
    cameraAlarmContainer.innerHTML="";
    // 采样并发送。
    manager.initCameras().then(() => {
        // 遍历所有摄像头并启动采样（每2秒一帧）,interval还是需要提取。等会再说。
        manager.cameras.forEach((_, deviceId) => {
        manager.startSampling(deviceId,socket, sample_interval);
        });
    });
    camera_state = 1;
    startCameraBtn.disabled = true;
    startCameraBtn.classList.remove('bg-secondary', 'hover:bg-secondary/90', 'text-white');
    startCameraBtn.classList.add('bg-gray-200', 'text-gray-400', 'cursor-not-allowed');
    stopCameraBtn.disabled = false;
    stopCameraBtn.classList.remove('bg-gray-500', 'text-white', 'cursor-not-allowed');
    stopCameraBtn.classList.add('bg-red-500', 'hover:bg-red-600', 'text-white', 'shadow-md', 'hover:shadow-lg');
});
const bufferImage = new Image();
async function displayCamerasFrames(DEVICEID,INTERVAL) {
    // 获取卡片的img,deviceID没有使用，导致获取到的是第一个img
    const frame_card = document.getElementById(DEVICEID);
    const frame_img = frame_card.querySelector('img');
    console.log("获取卡片 img",frame_img);
    if(frame_img){
            // 获取frames
        let frames = cameras_frames.get(DEVICEID)['frames'];
        while (frames.length > 0) {
            // 不需要调整，直接获取deviceId的卡片，更新。
            const url = frames.shift();
            bufferImage.onload = () => {
                frame_img.src = url;
                URL.revokeObjectURL(url); // 释放 URL 对象
            };
            bufferImage.src = url;
            await sleep(INTERVAL);
        }
    }else{
        console.error("未获取卡片 img，也许 无法访问摄像头");
    }
}

function getLabel(deviceId){
     for (const [index, device] of video_input_list.entries()){
         if(device.deviceId === deviceId){
             return device.label;
         }
     }
}
socket.on("processed_camera_frame",(data)=>{
    console.log("processed_camera_frame",data);
    const blob = new Blob([data['frame']], { type: 'image/jpeg' });
    const url = URL.createObjectURL(blob);
    const cls_conf = data['cls_conf'];
    const deviceId = data['deviceId'];
    let flag_frames = cameras_frames.get(deviceId);
    const result = check_alarm(cls_conf,frame_count,flag_frames['recentFireConfidences'],flag_frames['recentSmokeConfidences'],FIRE_CONFIDENCE_THRESHOLD,SMOKE_CONFIDENCE_THRESHOLD,PROPORTION_THRESHOLD);
    // cameraAlarmContainer;
    const now = new Date();
    const dateTime = now.toLocaleString();
    const time = now.toLocaleTimeString();
    // 定义获取label和roomID的函数
    const cameraLabel = getLabel(deviceId);
    const roomId = mappingCameraId2RoomId(deviceId,cameraId2RoomId);
    console.log("接收帧时间：",time);
    if (result.fire === 1) {
        const newAlarm = `
            <div class="p-3 bg-white rounded-lg border-l-4 border-red-500 shadow-sm hover:shadow-md transition-all duration-200 cursor-pointer transform hover:-translate-y-1">
                <!-- 警报类型和时间 -->
                <div class="flex justify-between items-center mb-2">
                    <div class="flex items-center gap-2">
                        <div class="w-8 h-8 bg-red-100 rounded-full flex items-center justify-center">
                            <i class="fa fa-fire text-red-500"></i>
                        </div>
                        <h4 class="font-medium text-red-800 truncate max-w-[150px]" title="火焰警报">
                            火焰警报
                        </h4>
                    </div>
                    <span class="text-xs text-gray-500 bg-gray-100 px-2 py-0.5 rounded" title="${dateTime}">
                        ${time}
                    </span>
                </div>

                <!-- 摄像头和房间信息（**强制垂直布局**，确保不遮挡） -->
                <div class="flex flex-col gap-1.5"> <!-- 关键：flex-col 强制垂直排列 -->
                    <!-- 房间ID -->
                    <div class="flex items-center gap-1.5 truncate">
                        <i class="fa fa-map-marker text-gray-400"></i>
                        <span class="text-gray-700" title="${roomId}">${roomId}</span> <!-- 保留悬停提示 -->
                    </div>
                    <!-- 摄像头标签 -->
                    <div class="flex items-center gap-1.5 truncate">
                        <i class="fa fa-video-camera text-gray-400"></i>
                        <span class="text-gray-700" title="${cameraLabel}">${cameraLabel}</span> <!-- 保留悬停提示 -->
                    </div>
                </div>
                <!-- 动态闪烁的报警指示器 -->
                <div class="absolute top-2 right-2">
                    <div class="w-2 h-2 bg-red-500 rounded-full animate-pulse"></div>
                </div>
            </div>`;
        cameraAlarmContainer.innerHTML += newAlarm;
        // 将滚动条滚动到最底部
        cameraAlarmContainer.scrollTop = cameraAlarmContainer.scrollHeight;
        if(!artAlarm.readingContent['fire'].includes(roomId)){
            artAlarm.readingContent['fire'].push(roomId);
        }
        artAlarm.startReading();
    }else{
        if(artAlarm.readingContent['fire'].includes(roomId)){
            let index = artAlarm.readingContent['fire'].indexOf(roomId);
            artAlarm.readingContent['fire'].splice(index,1);
        }
    }
    if (result.smoke === 1) {
        const newAlarm = `<!-- 烟雾警报记录 -->
          <div class="p-3 bg-white rounded-lg border-l-4 border-yellow-500 shadow-sm hover:shadow-md transition-all duration-200 cursor-pointer transform hover:-translate-y-1 relative group">
            <!-- 警报类型和时间 -->
            <div class="flex flex-col sm:flex-row justify-between items-start sm:items-center mb-3 gap-2">
                <div class="flex items-center gap-2">
                    <div class="w-8 h-8 bg-yellow-100 rounded-full flex items-center justify-center group-hover:scale-110 transition-transform">
                        <i class="fa fa-smog text-yellow-500"></i>
                    </div>
                    <h4 class="font-medium text-yellow-800 truncate max-w-[150px]" title="烟雾警报">
                        烟雾警报
                    </h4>
                </div>
                <span class="text-xs text-gray-500 bg-gray-100 px-2 py-0.5 rounded" title="${dateTime}">
                    ${time}
                </span>
            </div>

            <!-- 摄像头和房间信息（垂直布局，确保不遮挡） -->
            <div class="flex flex-col gap-2 text-sm">
                <!-- 房间ID（独立一行，增加图标大小） -->
                <div class="flex items-center gap-2 truncate">
                    <i class="fa fa-map-marker text-gray-500 text-lg"></i>
                    <span class="text-gray-700 font-medium truncate" title="${roomId}">${roomId}</span>
                </div>
                <!-- 摄像头标签（独立一行，使用标签样式） -->
                <div class="flex items-center gap-2 truncate">
                    <i class="fa fa-video-camera text-gray-500"></i>
                    <span class="text-gray-700" title="${cameraLabel}">${cameraLabel}</span>
                </div>
            </div>

            <!-- 动态闪烁的报警指示器 -->
            <div class="absolute top-2 right-2">
                <div class="w-2 h-2 bg-yellow-500 rounded-full animate-pulse"></div>
            </div>
        </div>`;
        cameraAlarmContainer.innerHTML += newAlarm;
        // 将滚动条滚动到最底部
        cameraAlarmContainer.scrollTop = cameraAlarmContainer.scrollHeight;
        if(!artAlarm.readingContent['smoke'].includes(roomId)){
            artAlarm.readingContent['smoke'].push(roomId);
        }
        artAlarm.startReading();
    }else{
        if(artAlarm.readingContent['smoke'].includes(roomId)){
            let index = artAlarm.readingContent['smoke'].indexOf(roomId);
            artAlarm.readingContent['smoke'].splice(index,1);
        }
    }
    // frame 放入对应的中
    if(cameras_frames.has(deviceId)){
        flag_frames['frames'].push(url);
        //console.log(`push processed camera frame to ${deviceId},frames length:${flag_frames['frames'].length},isLoading:${flag_frames['isLoading']}`);
        //console.log(`对比结果：${flag_frames['frames'].length},${sample_interval},${!flag_frames['isLoading']}`);
        if (flag_frames['frames'].length >= frame_count && !flag_frames['isLoading']) {
            console.log("start to display camera frames!");
            flag_frames['isLoading'] = true;
            //需要重写。
            displayCamerasFrames(deviceId,sample_interval);
            flag_frames['isLoading'] = false;
        }
    }

});
stopCameraBtn.addEventListener('click', () => {
    artAlarm.isStopped = true;
    console.log("停止采样以及发送");
    manager.cameras.forEach((_, deviceId) => {
        manager.stopSampling(deviceId);
    });
    camera_state = 0;
    startCameraBtn.disabled = false;
    startCameraBtn.classList.remove('bg-gray-200', 'text-gray-400', 'cursor-not-allowed');
    startCameraBtn.classList.add('bg-secondary', 'hover:bg-secondary/90', 'text-white');
    stopCameraBtn.disabled = true;
    stopCameraBtn.classList.remove('bg-red-500', 'hover:bg-red-600', 'text-white', 'shadow-md', 'hover:shadow-lg');
    stopCameraBtn.classList.add('bg-gray-500', 'text-white', 'cursor-not-allowed');
});
applyCameraSampleRate.addEventListener('click',function (){
    sample_interval = cameraSampleRate.value;
    frame_count = Math.min(Math.floor(1000/sample_interval*delay_time),MAX_FRAME_COUNT);
    console.log(`frame count 被设置为${frame_count}`);
    console.log(`sample_interval 被设置为:${sample_interval},接下来重启摄像头。`);
    if(camera_state === 1){
        stopCameraBtn.click();
        startCameraBtn.click();
    }
});